package com.karumi.dexter.simple;

import com.karumi.dexter.Dexter;
import com.karumi.dexter.PermissionToken;
import com.karumi.dexter.listener.OnDialogButtonClickListener;
import com.karumi.dexter.listener.PermissionRequestErrorListener;
import com.karumi.dexter.listener.multi.CompositeMultiplePermissionsListener;
import com.karumi.dexter.listener.multi.MultiplePermissionsListener;
import com.karumi.dexter.listener.multi.PopupOnAnyDeniedMultiplePermissionsListener;
import com.karumi.dexter.listener.single.CompositePermissionListener;
import com.karumi.dexter.listener.single.DialogOnDeniedPermissionListener;
import com.karumi.dexter.listener.single.PermissionListener;
import com.karumi.dexter.listener.single.PopupOnDeniedPermissionListener;

import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;
import ohos.agp.components.Component;
import ohos.agp.components.DirectionalLayout;
import ohos.agp.components.Text;
import ohos.agp.utils.Color;
import ohos.agp.utils.Point;
import ohos.agp.window.service.DisplayAttributes;
import ohos.agp.window.service.DisplayManager;
import ohos.app.Context;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.security.SystemPermission;

/**
 * 权限请求首页
 */
public class MainAbility extends Ability {

    private static final String CAMERA_PERMISSION_NAME = "ohos.permission.CAMERA";
    private static final String MICROPHONE_PERMISSION_NAME = "ohos.permission.MICROPHONE";
    private static final String LOCATION_PERMISSION_NAME = "ohos.permission.LOCATION";
    private static final String READ_MEDIA_PERMISSION_NAME = "ohos.permission.READ_MEDIA";

    private MultiplePermissionsListener allPermissionsListener;
    private SampleBackgroundThreadPermissionListener cameraPermissionListener;
    private PermissionListener locationPermissionListener;
    private PermissionListener audioPermissionListener;
    private PermissionListener microPhoneListener;
    private PermissionRequestErrorListener errorListener;

    private DirectionalLayout contentView;
    private Text cameraView;
    Text locationView;
    Text readMediaView;
    private Text cameraViewText;
    Text locationViewText;
    Text microPhoneText;
    Text readMediaViewText;

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_main);
        contentView = (DirectionalLayout) findComponentById(ResourceTable.Id_main_root);

        createPermissionListeners();

        // request all
        findComponentById(ResourceTable.Id_btn_all)
                .setClickedListener(
                        new Component.ClickedListener() {
                            @Override
                            public void onClick(Component component) {
                                requestAllPermission();
                            }
                        });
        // camera
        cameraView = (Text) findComponentById(ResourceTable.Id_btn_camera);
        cameraViewText = (Text) findComponentById(ResourceTable.Id_txt_camera);
        cameraView.setClickedListener(
                new Component.ClickedListener() {
                    @Override
                    public void onClick(Component component) {
                        cameraPermission();
                    }
                });
        // location
        locationView = (Text) findComponentById(ResourceTable.Id_btn_location);
        locationViewText = (Text) findComponentById(ResourceTable.Id_txt_location);
        locationView.setClickedListener(
                new Component.ClickedListener() {
                    @Override
                    public void onClick(Component component) {
                        locationPermission();
                    }
                });
        // micro phone
        microPhoneText = (Text) findComponentById(ResourceTable.Id_txt_mphone);
        findComponentById(ResourceTable.Id_btn_mphone)
                .setClickedListener(
                        new Component.ClickedListener() {
                            @Override
                            public void onClick(Component component) {
                                microPhonePermission();
                            }
                        });
        // read_media
        readMediaView = (Text) findComponentById(ResourceTable.Id_btn_read_media);
        readMediaViewText = (Text) findComponentById(ResourceTable.Id_txt_read_media);
        readMediaView.setClickedListener(
                new Component.ClickedListener() {
                    @Override
                    public void onClick(Component component) {
                        readMediaPermission();
                    }
                });
    }

    // 多个请求最好以这种方式
    private void requestAllPermission() {
        Dexter.withContext(this)
                .withPermissions(CAMERA_PERMISSION_NAME, LOCATION_PERMISSION_NAME)
                .withListener(allPermissionsListener)
                .withErrorListener(errorListener)
                .check();
    }

    // 单个请求最好用这个方法，有底部弹框
    private void locationPermission() {
        Dexter.withContext(this)
                .withPermission(LOCATION_PERMISSION_NAME)
                .withListener(locationPermissionListener)
                .withErrorListener(errorListener)
                .check();
    }

    // 单个请求dialog弹框，这种方式也可以
    private void microPhonePermission() {
        Dexter.withContext(this)
                .withPermission(MICROPHONE_PERMISSION_NAME)
                .withListener(microPhoneListener)
                .withErrorListener(errorListener)
                .check();
    }

    private void cameraPermission() {
        new EventHandler(EventRunner.getMainEventRunner())
                .postTask(
                        new Runnable() {
                            @Override
                            public void run() {
                                Dexter.withContext(MainAbility.this)
                                        .withPermission(CAMERA_PERMISSION_NAME)
                                        .withListener(cameraPermissionListener)
                                        .withErrorListener(errorListener)
                                        .onSameThread()
                                        .check();
                            }
                        });
    }

    // 或者这种方式有dialog
    private void readMediaPermission() {
        Dexter.withContext(this)
                .withPermission(READ_MEDIA_PERMISSION_NAME)
                .withListener(audioPermissionListener)
                .withErrorListener(errorListener)
                .check();
    }

    private void createPermissionListeners() {
        PermissionListener feedbackViewPermissionListener = new SamplePermissionListener(this);
        MultiplePermissionsListener feedbackViewMultiplePermissionListener = new SampleMultiplePermissionListener(this);

        // request all listener
        allPermissionsListener =
                new CompositeMultiplePermissionsListener(
                        feedbackViewMultiplePermissionListener,
                        PopupOnAnyDeniedMultiplePermissionsListener.Builder.with(
                                getContext(), ResourceTable.String_all_permissions_denied_feedback)
                                .withOpenSettingsButton(ResourceTable.String_permission_rationale_settings_button_text)
                                .build());

        locationPermissionListener =
                new CompositePermissionListener(
                        feedbackViewPermissionListener,
                        PopupOnDeniedPermissionListener.Builder.with(
                                getContext(), ResourceTable.String_contacts_permission_denied_feedback)
                                .withOpenSettingsButton(ResourceTable.String_permission_rationale_settings_button_text)
                                .build());

        cameraPermissionListener = new SampleBackgroundThreadPermissionListener(this);

        // macroPhone
        PermissionListener microPhonePermissionListener = new MicroPhonePermissionListener();
        PermissionListener microDialogListener =
                DialogOnDeniedPermissionListener.Builder.withContext(this)
                        .withMessage("我需要获取该设备的麦克风权限才能使用该功能，请授权一下")
                        .withTitle("获取录音权限")
                        .withButtonText(
                                "重新获取",
                                new OnDialogButtonClickListener() {
                                    @Override
                                    public void onClick() {
                                        microPhonePermission();
                                    }
                                })
                        .withNegativeButtonText("取消")
                        .build();
        microPhoneListener = new CompositePermissionListener(microPhonePermissionListener, microDialogListener);

        PermissionListener dialogOnDeniedPermissionListener =
                DialogOnDeniedPermissionListener.Builder.withContext(this)
                        .withTitle(ResourceTable.String_read_media_permission_denied_dialog_title)
                        .withMessage(ResourceTable.String_all_permissions_denied_feedback)
                        .withButtonText(ResourceTable.String_simple_ok)
                        .withIcon(ResourceTable.Media_icon)
                        .build();

        audioPermissionListener =
                new CompositePermissionListener(feedbackViewPermissionListener, dialogOnDeniedPermissionListener);

        errorListener = new SampleErrorListener();
    }

    /**
     * 权限拒绝后弹框
     */
    private void dialogDenied() {
        DialogOnDeniedPermissionListener listener =
                DialogOnDeniedPermissionListener.Builder.withContext(this)
                        .withTitle(ResourceTable.String_read_media_permission_denied_dialog_title)
                        .withMessage(ResourceTable.String_all_permissions_denied_feedback)
                        .withButtonText(ResourceTable.String_simple_ok)
                        .withIcon(ResourceTable.Media_icon)
                        .build();
    }

    /**
     * 权限授权
     * @param permission 单个权限
     */
    public void showPermissionGranted(String permission) {
        Text feedbackView = getFeedbackViewForPermission(permission);
        feedbackView.setText(ResourceTable.String_permission_granted_feedback);
        feedbackView.setTextColor(Color.GREEN);
    }

    /**
     * 权限被拒绝
     * @param permission permission
     * @param isPermanentlyDenied isPermanentlyDenied
     */
    public void showPermissionDenied(String permission, boolean isPermanentlyDenied) {
        Text feedbackView = getFeedbackViewForPermission(permission);
        feedbackView.setText(
                isPermanentlyDenied
                        ? ResourceTable.String_permission_permanently_denied_feedback
                        : ResourceTable.String_permission_denied_feedback);
        feedbackView.setTextColor(Color.RED);
    }

    /**
     * 请求showPermissionRationale
     * @param token 接口请求方法token
     */
    public void showPermissionRationale(PermissionToken token) {
        token.continuePermissionRequest();
    }

    private Text getFeedbackViewForPermission(String name) {
        Text feedbackView = null;

        switch (name) {
            case CAMERA_PERMISSION_NAME:
                feedbackView = cameraViewText;
                break;
            case LOCATION_PERMISSION_NAME:
                feedbackView = locationViewText;
                break;
            case READ_MEDIA_PERMISSION_NAME:
                feedbackView = readMediaViewText;
                break;
            case MICROPHONE_PERMISSION_NAME:
                feedbackView = microPhoneText;
                break;
            default:
                break;
        }

        return feedbackView;
    }

    @Override
    public void onRequestPermissionsFromUserResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsFromUserResult(requestCode, permissions, grantResults);
        Dexter.onRequestPermissionsFromUserResult(requestCode, permissions, grantResults);
    }

    public static Point getDisplayAttributes(Context context) {
        DisplayAttributes displayAttributes =
                DisplayManager.getInstance().getDefaultDisplay(context).get().getAttributes();
        Point size = new Point(displayAttributes.width, displayAttributes.height);
        float xDpi = displayAttributes.xDpi;
        float yDpi = displayAttributes.yDpi;
        float densityDpi = displayAttributes.densityDpi;
        float densityPixels = displayAttributes.densityPixels;
        float scalDensity = displayAttributes.scalDensity;
        return size;
    }
}
